home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / serial / dcon0.000 / dcon0 / dcon0.96 / dcon.doc < prev    next >
Text File  |  1996-07-20  |  30KB  |  929 lines

  1. #!/usr/bin/more
  2. /*
  3.  * dcon version 0.9 April 1996.
  4.  *
  5.  * Copyright (C) 1989,1996  Daniel Chouinard
  6.  *
  7.  * Permission to use, copy, and distribute this software and its
  8.  * documentation for any purpose without fee is hereby granted,
  9.  * provided that the above copyright notice appear in all copies and
  10.  * that both that copyright notice and this permission notice appear
  11.  * in supporting documentation.
  12.  *
  13.  * Permission to modify the software is granted, but not the right to
  14.  * distribute the modified code so that only one version of the language
  15.  * syntax may be agreed upon.
  16.  *
  17.  * This software is provided "as is" without express or implied warranty.
  18.  *
  19.  *
  20.  * Send your comments suggestions, or bug reports to
  21.  *  danny@limestone.kosone.com
  22.  *
  23.  *  Check for later versions of this package in case I (the author) changes
  24.  *  addresses.
  25.  */
  26.  
  27. dcon.doc : Documentation for dcon
  28.  
  29. -- Synopsis
  30.  
  31. dcon is a scripting language interpreter useful for establishing
  32. communications on serial lines.  Some uses included automated scripts
  33. to connect to ISP's, tech support clients, BBS'es, etc... dcon has some
  34. features that are rarely found in other utilities of the same type.
  35.  
  36. -- Features
  37.  
  38.   - Simple, BASIC-like script language.
  39.   - Command-line and file sourcing of script.
  40.   - Multi-response waitfor.
  41.   - waitquiet permits line stabilization.
  42.   - In-line text capture.
  43.   - Multi-process support: fork, wait, kill, exit.
  44.   - Debugging verbose and log output.
  45.   - logging to file.
  46.   - Flow control: goto, gosub, return, if, else.
  47.   - Low-impact on system resources.
  48.   - Time commands and functions.
  49.   - String manipulations.
  50.   - Environment manipulation: env(), putenv.
  51.   - External utilities system calls: system, exec.
  52.  
  53.  
  54. -- History
  55.  
  56. Sat Jul 20 08:19:13 EDT 1996
  57.    - Ameliorated error reporting.
  58.  
  59. Fri Jul 19 22:29:37 EDT 1996
  60.    - Got a bug report from Glen Thigpen that dcon-0.91 reports "Token too long"
  61.      errors.  Found that dcon didn't deal with non-terminated last lines
  62.      properly.
  63.  
  64. Mon Apr 29 21:38:04 EDT 1996
  65.    - Got a bug report from J. Van Koll reporting that the included
  66.      ppp-ex.scr had two lines that were truncated.  Modified ppp-ex.scr
  67.  
  68.   I wrote most (90%) of dcon back in 1989 (it shows in the source code)
  69. when I started doing Unix Apps tech support mostly by modem to customer
  70. systems.  I was tired of typing all those passwords and funny call-charging
  71. codes everytime I used cu.  Also, the company I worked for needed a system
  72. that would log call times and estimated costs.  Thus dcon was born.
  73. Fast forward six or seven years (today) and I was using pppd to connect to
  74. my ISP site.  I was somewhat happy with 'chat' but found it lacking flow
  75. control and multiple respone checks from "atdt..." I wanted it to do
  76. different things for "no carrier", "no dial tone", and "busy".
  77. Although I thought that chat's author would probably add more features
  78. to it someday, although minicom probably does the work already, I found
  79. dcon.c on one of my old 45M tapes.  So, I tried compiling it on my Linux
  80. box and, lo and behold, wonder of wonders, it did.
  81. In the end, I added a few things to it (kill, fork, wait, 1/100 sec. times)
  82. and there you are.
  83.  
  84. In this package, you will find source code (don't laugh), documentation and
  85. script examples that should enable you to become a dcon script author in
  86. minutes.  It's quite easy if you've programmed in any language, especially
  87. (don't laugh) BASIC.  It's nowhere near perfect (don't laugh), the getvalue()
  88. function is brain-dead (don't laugh), has only integer and string variables
  89. (don't laugh), in the a-z range (don't laugh), a limitied set of operators,
  90. functions and commands.  You can stop laughing now.
  91. For all its shortcomings, dcon is great to connect you to the outside world
  92. quickly, intelligently, and with versatility.  Please stop laughing.
  93.  
  94. The example scripts in this package are:
  95.  
  96. Filename        Description
  97. -------------   --------------------------------------------------------------
  98. ppp-ex.scr      Script to connect to an Internet service provider using ppp
  99.                 with the ISP using an Annex terminal server.
  100.  
  101. tst.scr         Script to test dcon's functionnality.  All tests do not use
  102.                 any communication equipment
  103.  
  104. loopback.scr    Script to test with a loopback installed on a COM port.
  105.  
  106.  
  107. If you would like to contribute more scripts to be included in this
  108. package, please do so!  scripts for ISPs, BBSs, using cu, sz, rz, kermit,
  109. minicom, seyon, or whatever.  Just send them thru E-Mail to the author.
  110. Please comment your scripts.
  111.  
  112.  
  113. -- Installation
  114.  
  115.   make dcon                (cc -O2 -o dcon dcon.c  if you're a purist)
  116.   mv dcon /usr/local/bin/  (anywhere that's pointed by your PATH)
  117.   cp dcon.doc .....        (anywhere you keep your text doc files)
  118.  
  119. Note: Makefile not needed.
  120.  
  121. -- Calling syntax
  122.  
  123. dcon [-v] [-e] [-t x] [-d device] [-s "script..."] [scriptfile]
  124.  
  125.   -v  : Turn verbose on.  dcon will print the script and an execution trace
  126.         on stderr.  This can be re-directed with "2>/tmp/output".
  127.   -e  : Turn communication echo on.  This will display incoming characters
  128.         as they are received on stderr.
  129.   -t x: Set character x as line separator.  This is used to indicate line
  130.         cuts when the script is specified on the command line (-s...)
  131.   -d x: This opens the serial device x prior to executing the script.
  132.         Optionnal.  This can also be done in the script proper.
  133.   -s x: Specify script.  If both -s and scriptfile are specified, scriptfile
  134.         is concatenated at the end of the command-line specified script.
  135.      x: Specify script file.  The script file is read entirely in memory
  136.         before it's executed.  This argument MUST be specified last.
  137.  
  138.  Note that it's "-d /dev/cua1", not "-d/dev/cua1".
  139.  
  140. -- Simple examples
  141.  
  142. - Execute script
  143. dcon script.scr
  144.  
  145. - Execute script with parameter passing
  146. dcon -t ";" -s "let \$n=555-4411; let \$u=username" script.scr
  147. ( This attributes 555-4411 to variable $n and "username" to $u before
  148.   the script is executed )
  149.  
  150. - Shell script example
  151. #!/bin/sh
  152. dcon -s '
  153.   open com /dev/cua1
  154.   set com 38400n81
  155.   send "atdt555-4411^m"
  156.   waitfor 60 "connect"
  157.   print "Connected!"
  158.   exec "cu -l /dev/cua1 -s 38400"
  159. '
  160.  
  161. ( While this works fine, it should be noted that the single quote should
  162.   not be used throughout the script, unless escaped with a back-slash )
  163.  
  164.  
  165. -- Connect to ISP using PPP script
  166.  
  167. Here's a script I'm using to connect to my ISP.  It's using an Annex terminal
  168. server (very popular) so changing it to your needs should be pretty trivial.
  169. This script is also furnished in non-commented form as "ppp-ex.scr"
  170. The procedure reads:
  171. Wait for login prompt, send user's name, wait for password prompt,
  172. send password, wait for annex prompt, send "ppp", start up ppp, end with
  173. ppp-off.  Of course, this script does a bit more...
  174.  
  175. ----------------------------Cut here  8< -----------------------------------
  176. # dcon script to dial-in to ISP
  177. # This is a comment.  Note that "rem" can also be used.
  178.  
  179. let $n="555-4411"                                 # Phone number
  180. let $u="danny"                                    # Username
  181. let $p="rubataga"                                 # Password
  182. let $l=/root/.isplog                              # Log file
  183. open com /dev/cua1                                # Open com port.
  184. set com 38400n81                                  # No parity, one stop
  185. set senddelay 0.10                                # In-between character delay.
  186. let $a=$rpipe("uname -n")                         # Get name of node
  187. if $a="bill" let $n="9,"+$n  set com 19200n81     # From office differences
  188.  
  189. # Note that the bit after "then" in an if statement can be compounded commands
  190. # ie. commands seperated by spaces.  If the condition is false, if skips the
  191. # script to the next line.  By the way, "then" is optionnal.
  192. # if a=1 then let $b="blah" is also fine.
  193.  
  194. # Note that while dcon's variables are integers, time values are
  195. # indicated by floating point constants (resolution: 1/100th of a sec.)
  196. # Because they can only be constants, you cannot do
  197. # let a=3
  198. # waitquiet a 1
  199. #           ^ will evaluate to zero, not 3.
  200. # I didn't want to use floats as much as possible cuz' that's kinda slow on
  201. # some systems. (1996 note: Remember: This is a really old program(7 years))
  202.  
  203. let n=0                                           #Count how many times
  204. :reset
  205. # That's a label so "goto" may get back here.
  206. inc n                                             #Increment count
  207. if n>3 goto error                                 #Can't reset?
  208. print "\nResetting modem...\n"                    #Don't forget new-lines!
  209. waitquiet 5 0.5                                   #1/2 second quiet., 5 max.
  210. if % = -1 goto error                              #-1 is timeout reached.
  211. send "ATZ^m"                                      #Send ATZ
  212. waitfor 5 "ok"                                    #Modem responds with "ok"
  213. if % != 0 goto reset                              #If not, reset it again.
  214.  
  215. let n=0
  216. :dial
  217. waitquiet 2 0.5                                   #Wait for 1/2 sec. quiet
  218. if % = -1 goto error
  219. inc n                                             #Count dial attempts
  220. let $a=$mid($time(),11,8)                         #Get time as "23:59:59"
  221. print "\r",$a," Dial attempt #",n                 #Print it on-screen
  222. send "ATX4DT"+$n+"^m"                             #Send dial string
  223. waitfor 50 "connect","busy","no dial tone","no carrier"
  224.  
  225. # Wait for modem response, up to 50 seconds.  Note that get, waitfor and 
  226. # waitquiet store their result code in % (Like %errorlevel% in dos).
  227. # A time-out would be indicated by -1 in %.
  228.  
  229. # Note that strings (like the next one) can contain \xxx octal,
  230. # \x (b=backspace,t=tab,f=formfeed,n=newline,r=return, and escape ',",\ )
  231. # ^x notation. (^m=Carriage return)
  232.  
  233. if % = 1 print " Busy" sleep 2 print "\b\b\b\b\b     " goto dial
  234. if % = 2 print "\n\nNo dial tone! Check phone line!\n" goto error
  235. if % = -1 send " " sleep 1 goto dial
  236. if % != 0 goto error
  237.  
  238. get 5 " ^m" $c
  239.  
  240. # Get response from modem for no more than 5 seconds up to a space or a
  241. # carriage return and put it in string variable c.  Pretty cool.
  242. # At this point, the modem just said "CONNECT" (which waitfor swallowed)
  243. # so we want what's after that (usually connect speed and protocols used).
  244. # Ex.: CONNECT 1440/LAPM/V32/V42BIS/RUTABAGA/ARQ/MNP5/...^M
  245. #              ^ Catch from that point.       Stop here ^
  246. # Note that the delimiter characters are swallowed and ignored if received
  247. # before anything else.
  248. # (In this example, $c="1440/LAPM...", not " 1440/LAPM...")
  249.  
  250. let n=0
  251. print "\nConnected :",$c,"\n"
  252. sleep 1
  253. :wake
  254. print "Waiting for Login:...\n"
  255. waitfor 3 "ogin:"
  256. if % = 0 goto gotlogin
  257. print "Sending \^m\n"
  258. send "^m"
  259. inc n
  260. if n < 5 goto wake
  261. print "Could not get login.\n"
  262. goto error
  263. :gotlogin
  264. print "Logging-in...\n"
  265. send $u+"^m"
  266. print "Waiting for Password:\n"
  267. waitfor 10 "word:"
  268. if % != 0 print "Could not get password prompt!\n" goto error
  269. print "Sending password...\n"
  270. send $p+"^m"
  271. print "Waiting for annex prompt...\n"
  272. waitfor 10 "nnex:"
  273. if % != 0 goto error
  274. print "Starting ppp...\n"
  275. send "ppp^m"
  276. fork
  277. if % != 0 goto nonforked
  278.  
  279. # Ha, here's a funny thing. fork spawns a child process.  Both parent and
  280. # child processes continue to execute the script except that the child process
  281. # has 0 in % and the parent has the child's process ID in %.  This can be
  282. # used to differentiate between the two so that they may do two different
  283. # things.  In this example, the child calls pppd and the parent shows a clock.
  284. # Also, the parent monitors the keyboard so that when ENTER is pressed, it
  285. # closes the link (with ppp-off)
  286.  
  287. exec "/usr/lib/ppp/pppd lock defaultroute modem "+$dev()+" "+$baud()
  288. # Here the child executes pppd.  Note that exec replaces the current process
  289. # with a new one.  exec never returns.
  290. # Also note the $dev() and $baud string functions.  Coolness.
  291.  
  292. :nonforked
  293. # Here the parent process shows current and connect time while waiting for
  294. # the user to press ENTER and then closes the link and logs the call.
  295.  
  296. let $b=$time()     #$time()-> "Tue Apr  2 20:51:31 EST 1996"
  297. let d=time()       #time()-> number of seconds since 01/01/70 00:00:00GMT
  298. print "Type ENTER to close connection\n"
  299. print "Connected since ",$b,"\n"
  300. print "Connect ",$c," as ",$u,"\n"
  301. :tloop
  302. let $t=$hms(time()-d)
  303. # $hms(x) returns a string time representation in the form HH:MM:SS from
  304. # a number of seconds.  Here, we used variable d to note the start of the
  305. # connection.  So, later, time()-d is the number of seconds elapsed.
  306. # Thus, $hms(time()-d) Gives us "00:00:00", "00:00:01", "00:00:02",...
  307. # A chronometer, if you will.
  308.  
  309. print "\r",$mid($time(),11,8)," ->  ",$t," "
  310.  
  311. # This is neat.  Print a carriage return (no line-feed, so we stay on a single
  312. # line), the time ($mid as $mid(string,start,length) in Basic), and the
  313. # connect time.  Note that the first character of a string is $mid($s,0,1), not
  314. # $mid($s,1,1), as in Basic.  $mid can do the job of $left() and $right()
  315. # $left() is obvious, $right is $mid($s,len($s)-l,999) (l=characters desired)
  316.  
  317. sleep 1
  318. testkey
  319. # Testkey can only test for ENTER since the terminal device is in buffered
  320. # mode.  Oh well.
  321. if % = 0 goto tloop  # No key? Print the clock stuff again!
  322. # User typed enter, close link.
  323. system "/usr/lib/ppp/ppp-off"
  324. open file $l
  325. # open file appends to a file. ( $l here was defined at the beginning of this
  326. # script.  Or had you forgotten? )
  327. fprint $b," - ",$time()," -> ",$t,"\n"
  328. # Log beginning, end, and connect time.
  329. # print ->stdout, eprint ->stderr, fprint -> file, lprint ->verbose log.
  330. close file
  331. sleep 1
  332. exit 0
  333. :error
  334. print "\nGot error #",%,"!\n"
  335. exit 1
  336.  
  337. ----------------------------Cut here  8< -----------------------------------
  338.  
  339. -- Notes on invocation
  340.  
  341. For the previous example, I have a .fvwmrc line in my Menu pop-up that reads:
  342.  
  343.  Exec "ISP-PPP" /usr/bin/X11/rxvt -ls -geometry 40x4 -e dcon /root/scr/ppp.scr
  344.  
  345. This starts up a small window into which the script is executed.
  346. While I'm online I see a neat little timer (I pay for my internet access).
  347. When I want to disconnect from the ISP, I just type ENTER in the window and,
  348. click, it disconnects and the window closes.
  349.  
  350. From a VT, i just type "callisp" which is a shell script that reads:
  351. #!/bin/sh
  352. dcon /root/scr/ppp.scr
  353.  
  354. Leave it running there, switch to another VT and get back to it later.
  355.  
  356. Of course, if you plan to use this script or ppp-ex.scr, you'll have to change
  357. $u (your username), $p (your password), $n (your ISP number), where pppd
  358. is called from (if yours is not in /usr/lib/ppp), same for ppp-off, and you
  359. may have to change a few waitfors to reflect your ISP's prompts.  Log in to
  360. your ISP manually and write them down, then modify the script.  Try it.
  361. If you have problems, try 'set comecho on' to see what your ISP is saying.
  362. If your script terminates with an error, try calling it with the -v switch
  363. so that you may follow its execution step by step.
  364.  
  365.  
  366.  
  367. -- Programming manual
  368.  
  369. -- Commands
  370.  
  371. Command     : rem  Aliases: #, //
  372. Description : Remark.  Rest of line is ignored.
  373. Syntax      : Note that a space must follow "rem".
  374. Example:
  375.  
  376. #This is a remark
  377. // So is this
  378. rem And this.
  379.  
  380.  
  381. Command     : :
  382. Description : Notes an anchor point for goto or gosub
  383. Syntax      : Keyword must not contain any special characters
  384. Example:
  385.  
  386. :loop
  387. print "The time is ",$time(),"\n"
  388. sleep 1
  389. goto loop
  390.  
  391.  
  392. Command     : open
  393. Description : Opens a file or a communication device
  394. Syntax      : open com device, open com (stdin), open file FILE
  395. Example:
  396.  
  397. open com /dev/cua1
  398. set com 38400n81
  399. open file "/tmp/log"
  400. fprintf "This is a log\n"
  401. close file
  402.  
  403.  
  404. Command     : close
  405. Description : closes file previously opened with open
  406. Syntax      : close file
  407. Example:
  408.  
  409. See previous.
  410.  
  411. Command     : exec
  412. Description : Replaces current process with new one
  413. Syntax      : exec "command -args..."
  414. Example:
  415.  
  416. #Finished script, call cu.
  417. exec "cu -l "+$dev()+" -s "+$baud()
  418.  
  419.  
  420. Command     : exit
  421. Description : terminates script execution with exit code
  422. Syntax      : exit exit_code
  423. Example:
  424.  
  425. :error
  426. exit 1
  427. :exit_ok
  428. exit 0
  429.  
  430.  
  431. Command     : testkey
  432. Description : Tests keyboard for keystroke, returns 1 in % if present.
  433. Syntax      : testkey
  434. Notes       : Can only test for ENTER key.  Future versions of dcon will test
  435. Notes       : for more and return keycode in %.
  436. Example:
  437.  
  438. let n=1
  439. :loop
  440. print n," sheep... ZZZzzz...\n"
  441. sleep n
  442. inc n
  443. testkey
  444. if % = 0 goto loop
  445.  
  446.  
  447. Command     : fork
  448. Description : forks process into two.
  449. Syntax      : fork
  450. Notes       : % returns 0 for child process, new process ID for parent or
  451. Notes       : -1 for error.
  452. Example:
  453.  
  454. fork
  455. if % = -1 goto error
  456. if % = 0 goto child
  457. :parent
  458. ...
  459.  
  460. Command     : hset
  461. Description : Set the hundreds counter
  462. Syntax      : hset value
  463. Notes       : This command resets the hundreds of seconds counter to a value
  464. Notes       : for htime to start from.
  465. Example:
  466.  
  467. hset 0
  468. :loop
  469. print "Time in 1/100 of a sec.: ",htime(),"\n"
  470. sleep 0.01
  471. goto loop
  472.  
  473.  
  474. Command     : kill
  475. Description : sends a signal to a process
  476. Syntax      : kill signal processID
  477. Notes       : Both signal and processID are integer values.  Same as standard
  478. Notes       : unix kill except that signal aliases are not accepted.
  479. Notes       : 0 is returned in % if the signal could be sent, -1 otherwise.
  480. Notes       : Signal 0 can be used to detect process existance.
  481. Example:
  482.  
  483. fork
  484. let p=%
  485. if p = 0 goto child
  486. sleep 300
  487. kill 15 p
  488. sleep 1
  489. kill 0 p
  490. if % != 0 print "Child terminated\n" goto ok
  491. print "Could not terminate child!\n"
  492. kill 9 p
  493. sleep 1
  494. kill 0 p
  495. if % = 0 print "Could not kill child!\n" goto error
  496. print "Child killed.\n"
  497. :ok
  498. ...
  499.  
  500.  
  501. Command     : wait
  502. Description : wait for a child process to terminate
  503. Syntax      : wait
  504. Notes       : Process ID of terminated child is returned in %
  505. Example:
  506.  
  507. fork
  508. let p=%
  509. if p=0 goto child
  510. if p=-1 goto error
  511. print "Waiting for child to finish..."
  512. wait
  513. print "\n"
  514. if %!=p print "HA! wait didn't return the right process number!\n" goto error
  515. print "Child is done.\n"
  516.  
  517.  
  518. Command     : system
  519. Description : calls a system (unix) command
  520. Syntax      : system "command"
  521. Example:
  522.  
  523. :dir
  524. print "listing of directory ",$cwd(),\n"
  525. system "ls -l |more"
  526.  
  527.  
  528. Command     : cd
  529. Description : Change directory
  530. Syntax      : cd directory
  531. Notes       : -1 is returned in % if the change could not be made.
  532. Example:
  533.  
  534. cd "duh"
  535. if % != 0 print "Could not cd into duh.\n"
  536.  
  537.  
  538. Command     : input
  539. Description : input string from keyboard into string variable
  540. Syntax      : input $a
  541. Notes       : input terminates entry only with the ENTER key.  Spaces, tabs
  542. Notes       : and other funny characters are all stored in the variable.
  543. Example:
  544.  
  545. print "Enter your full name :"
  546. input $n
  547.  
  548.  
  549. Command     : get
  550. Description : get string from communication device
  551. Syntax      : get timeout "terminators" $string
  552. Notes       : timeout is a float constant, terminators is a list of characters
  553. Notes       : that, when received, terminate get.  Terminators are ignored when
  554. Notes       : received first.
  555. Example:
  556.  
  557. waitfor 60 "connect"
  558. if % != 0 goto error
  559. get 2 " ^m" $s
  560. print "Connection parameters: ",$s,"\n"
  561.  
  562.  
  563. Command     : print
  564. Description : print a comma-separated list of arguments
  565. Syntax      : print var,stringvar,"text",...
  566. Notes       : Spaces and newlines are not automatically added.
  567. Example:
  568.  
  569. let b=26
  570. let $c="text variables"
  571. print "Contstant text ",b," ",$c," time: ",$time(),"\n"
  572.  
  573.  
  574. Command     : eprint
  575. Description : print a comma-separated list of arguments on stderr
  576. Syntax      : eprint var,stringvar,"text",...
  577. Notes       : Like print but on the standard error file descriptor.  The error
  578. Notes       : output can be re-directed with "2>file" on the command line.
  579.  
  580.  
  581. Command     : fprint
  582. Description : print a comma-separated list of arguments in a file
  583. Syntax      : fprint var,stringvar,"text",...
  584. Notes       : Like print but appended to a file previously opened by open.
  585.  
  586.  
  587. Command     : lprint
  588. Description : print a comma-separated list of arguments to the log
  589. Syntax      : fprint var,stringvar,"text",...
  590. Notes       : Like print but printed like a log entry if verbose is on.
  591. Notes       : logging is sent to stderr.
  592.  
  593.  
  594. Command     : if
  595. Description : tests a condition
  596. Syntax      : if test_condition commands...
  597. Notes       : Conditionnaly executes commands if test condition is true.  Test
  598. Notes       : operators are =, != (not equal), <, and > which all apply to
  599. Notes       : integers and strings.  If test_condition is false, if skips to
  600. Notes       : the next line.
  601. Example:
  602.  
  603. if n>30 print "Oh-ho! too many sheep!\n" goto error
  604. if n=17 print "Hurray! we've got exactly enough sheep for a party!\n" goto party
  605. if n<17 print "Murray will have to get more sheep.\n" goto getmore
  606. if $z<"z" goto ...
  607.  
  608. Command     : else
  609. Description : Alternatively execute commands if last if tested false
  610. Syntax      : else commands...
  611. Example:
  612.  
  613. if l<350 print "Wow! Imagine that.\n"
  614. else print "Rush Limbaugh is indeed a big fat bastard.\n"
  615.  
  616.  
  617. Command     : goto
  618. Description : Sends execution somewhere else in the script
  619. Syntax      : goto label
  620. Example:
  621.  
  622. :loop
  623. print "I feel like murdering Bill Gates...\n"
  624. goto loop
  625.  
  626.  
  627. Command     : gosub
  628. Description : calls a subroutine
  629. Syntax      : gosub label
  630. Example:
  631.  
  632. gosub routine
  633. sleep 1
  634. gosub routine
  635. goto end
  636. :routine
  637. print "Time: ",$time()," Which is ",time()" seconds in the information era.\n"
  638. return
  639.  
  640. Command     : return
  641. Description : Returns from subroutine
  642. Syntax      : return
  643.  
  644.  
  645. Command     : waitquiet
  646. Description : Waits until communication line stops receiving for a time
  647. Syntax      : waitquiet timeout quiettime
  648. Notes       : both timeout and quiettime are floating time constants
  649. Notes       : with 1/100th sec. accuracy.  Usefull fo "swallowing" incoming
  650. Notes       : characters for a while or waiting for an unknown prompt.
  651. Example:
  652.  
  653. :closecon
  654. send "logoff^m"
  655. waitquiet 10 0.5
  656. send "yes^m"
  657.  
  658.  
  659. Command     : waitfor
  660. Description : Waits until one of a list of strings is received
  661. Syntax      : waitfor timeout "string1","string2","string3"...
  662. Notes       : Timeout is a floating time constant.  waitquiet returns
  663. Notes       : 0 for the first string received, 1 for the second, etc...
  664. Notes       : and -1 for a timeout.  Case is ignored by default unless
  665. Notes       : ignorecase is set to off.
  666. Example:
  667.  
  668. :dial
  669. send "atdt555-4411^m"
  670. waitfor 60 "no carrier","busy","no dial tone","voice","connect"
  671. if % = -1 goto timedout
  672. if % = 0 goto nocd
  673. if % = 1 goto redial
  674. if % = 2 goto error
  675. if % = 3 goto hohoho
  676. if % = 4 goto connected
  677.  
  678.  
  679. Command     : set
  680. Description : sets working parameters
  681. Syntax      : set parameter value
  682. Notes       :
  683.  
  684. Command                       Description
  685. ----------------------------- -------------------------------------------------
  686. set echo on|off               Keyboard echo on-screen
  687. set comecho on|off            Received characters echoed on-screen
  688. set senddelay time_constant   In-between character delay for 'send'
  689. set ignorecase on|off         Case sensitivity for 'waitfor'
  690. set clocal on|off             clocal on = ignore modem signals
  691. set umask octal_constant      file mode creation defaults.  See man umask
  692. set verbose on|off            verbose on = debug output enabled (lots)
  693. set com com_params            communication parameters. ex.: 19200n81, 300e71
  694.                                                              baud |||
  695.                                                           Parity--|||
  696.                                                              bits--||
  697.                                                        Stop bits----|
  698.  
  699. Example:
  700.  
  701. set echo off
  702. print "Password :"
  703. input $p
  704. print "\n"
  705. set echo on
  706. set comecho on
  707. set senddelay 0.1
  708. set ignorecase on
  709. set com 38400n81
  710. ...
  711.  
  712. Command     : inc
  713. Description : increments the content of an integer variable by 1.
  714. Syntax      : inc x
  715. Notes       : x is from a to z.
  716.  
  717.  
  718. Command     : dec
  719. Description : Decrements the content of an integer variable by 1.
  720. Syntax      : inc x
  721. Notes       : x is from a to z.  Note that "let x=x-1" also works.
  722.  
  723. Command     : let
  724. Description : does a variable assignment
  725. Syntax      : let var=content
  726. Example:
  727.  
  728. let a=5
  729. let b=(time()-a)+5
  730. let $c="Daniel "
  731. let $d=$c+" Chouinard"
  732.  
  733.  
  734. Command     : send
  735. Description : sends a string to the communication line (modem usually)
  736. Syntax      : send string
  737. Example:
  738.  
  739. send "atdt555-1212^m"
  740. send $g+"^m"
  741. send "The time is "+$time()+"^m^j"
  742.  
  743.  
  744. Command     : sleep
  745. Description : Pauses execution.
  746. Syntax      : sleep float_constant
  747. Notes       : float_constant is precise down to 1/100th sec, unless more
  748. Notes       : than 100 second, in which case the precision falls down to 1 sec.
  749.  
  750. Example:
  751.  
  752. sleep 0.06
  753. sleep 3
  754. sleep 86400 /* A whole day */
  755.  
  756.  
  757. Command     : putenv
  758. Description : sets an environement variable
  759. Syntax      : putenv "var=content"
  760. Notes       : Environement variables are automatically exported, never returned.
  761. Notes       : Children processes inherit the environment
  762.  
  763. Example:
  764.  
  765. ...
  766. putenv "SCRIPTDIR=/usr/lib/dcon/scripts"
  767. system "dothat"  # dothat reads env. var. SCRIPTDIR...
  768. ...
  769.  
  770. -- Integer functions
  771.  
  772. I-Function  : len
  773. Description : returns the length of a string
  774. Syntax      : let x=len($s)
  775. Notes       : "" is zero.
  776.  
  777. I-Function  : time
  778. Description : returns time in seconds since Jan 1, 00:00:00 1970 GMT
  779. Syntax      : let x=time()
  780. Notes       : Used to calculate time differences
  781.  
  782. I-Function  : htime
  783. Description : returns hundreds of seconds since start of script
  784. Syntax      : let x=htime()
  785. Notes       : Set to a specific value with 'hset'
  786.  
  787. I-Function  : pid
  788. Description : Returns process ID number of current process (dcon's)
  789. Syntax      : let x=pid()
  790. Notes       : 
  791.  
  792. I-Function  : ppid
  793. Description : Returns process ID number of parent process
  794. Syntax      : let x=ppid()
  795. Notes       : can be used by 'fork'ed child to detect parent process
  796.  
  797. I-Function  : baud
  798. Description : Returns current baudrate of communication line
  799. Syntax      : let x=baud()
  800. Notes       : See also $baud()
  801.  
  802.  
  803. I-Function  : val
  804. Description : returns value of string
  805. Syntax      : let x=val($x)
  806. Notes       : String is not an expression; must only contain [0-9] characters
  807. Notes       : Future versions of dcon will be able to evaluate expressions.
  808. Notes       : (Maybe) (This was written 6 years ago)
  809.  
  810.  
  811. -- String functions
  812.  
  813. S-Function  : time
  814. Description : Returns 24 character local time string
  815. Syntax      : let $x=$time()
  816. Notes       : Time is in this format: Mon Apr  8 14:21:22 1996
  817.                                       012345678901234567890123
  818.                                                 1         2
  819.  
  820. S-Function  : rpipe
  821. Description : Returns the first line from a system piped command
  822. Syntax      : let $x=$rpipe("/bin/ls |grep myfile")
  823. Notes       : Not very useful unless used with head, tail, grep, etc...
  824.  
  825. S-Function  : env
  826. Description : Returns content of an environment variable
  827. Syntax      : let $x=$env("HOME")
  828. Notes       : Non-existant variables return an empty string.
  829.  
  830. S-Function  : hms
  831. Description : Converts number of seconds into time string
  832. Syntax      : let $x=$hms(x)
  833. Notes       : Format is "HH:MM:SS".  Useful for chronometer displays
  834. Notes       : Use with 'time()', do not try to increment a variable every
  835. Notes       : second using 'sleep 1'.  (See ISP script example)
  836. Notes       : Format becomes "HHH:MM:SS" after 99 hours, 59 minutes, 59s...
  837.  
  838. S-Function  : dev
  839. Description : Returns current communication device pathname
  840. Syntax      : let $x=$dev()
  841. Notes       : defined by '-d' command line argument or 'open com'
  842.  
  843. S-Function  : cwd
  844. Description : Returns current working directory pathname
  845. Syntax      : let $x=$cwd()
  846. Notes       : defined by 'cd'
  847.  
  848. S-Function  : baud
  849. Description : Returns string representation of current baud rate
  850. Syntax      : let $x=$baud()
  851. Notes       : Defined by 'set com'
  852.  
  853. S-Function  : mid
  854. Description : Returns midsection of a string
  855. Syntax      : let $x=$mid($s,s,l)
  856. Notes       : $s=Source string,s=start, l=length
  857. Notes       : s must be less than the length of the string, l can be some
  858. Notes       : huge number (9999) to return the right side of a string to
  859. Notes       : the end.  the first character of a string is position 0, not 1.
  860. Notes       : $right() can be done with: $mid($s,strlen($s)-l,l)
  861.  
  862.  
  863. -- Test operators
  864.  
  865. Operator Description  Example       Result
  866. =        equal        if 1+2=3      yes
  867. !=       not equal    if 1+2!=3     no
  868. >        Greater than if 1+3>3      yes
  869. <        Less than    if 1+3<3      no
  870.  
  871. Strings can be compared using the same operators.
  872. "aaa" < "aab",  "aaaa" > "aaa", "Test" != "test", "One" = "One", "A" > "a"
  873. Note that 'set ignorecase on' does NOT apply to string comparisons.
  874.  
  875.  
  876. -- Expression operators
  877.  
  878. Operator  Description      Example           Result
  879. +         Addition         let a=2+2         4
  880. +         Concatenation    let $b="aa"+"bb"  "aabb"
  881. -         Substraction     let e=2-5         -3
  882. *         Multiplication   let f=11*2        22
  883. /         Division         let g=34/11       3
  884. &         Bit-Wise AND     let h=42&7        2
  885. |         Bit-Wise OR      let a=42|5        47
  886. ^         Bit-Wise XOR     let a=42^7        45
  887.  
  888. Mixed expression examples:
  889.  
  890. #Returns number of seconds since 00:00:00
  891. let $t=$time() #Take a snapshot.
  892. let a=(val(mid$($t,11,2))*3600)+(val(mid$($t,14,2))*60)+val(mid$($t,17,2))
  893. #Notice the extra sets of parenthesis because dcon's expression evaluator
  894. #is brain-dead.
  895. #For example, 5-2+1 should give you 4, right?  Well, according to getvalue(),
  896. #it actually gives 2, because it does it somewhat from right to left.
  897. #So to evaluate 5-2+1 correctly, use (5-2)+1.  If you're using simple, two-
  898. #element calculations, don't worry about it.  5-2 will give you 3.
  899.  
  900. #Concatenation  (Calls cu)
  901. exec "cu -l "+$dev()+" -s "+$baud()"
  902.  
  903. #In a test condition
  904. if a+c > strlen($c) goto toolong
  905.  
  906. #String comparison
  907. let $t=$mid($time(),11,8)
  908. if $t > "19:59:59" print "Too late for that!\n" goto toolate
  909. if $t < "08:00:00" print "Too early!\n" goto tooearly
  910. if $t = "00:00:00" print "Oh god!  It's Twinkee time!\n"
  911.  
  912.  
  913. -- Known bugs
  914.  
  915. The expression parser!
  916.  
  917. -- Todo
  918.  
  919. Man page
  920. Test forked processed closing com device contention
  921. Option: locking (uucp? What's the standard?)
  922. Better testkey (Change stdin mode to raw, update input, system, exec & exit)
  923. getcomchar() (Get one byte from com so a dumb term could be written in a
  924.               script.  Must be done only after testkey)
  925. Use getopt()
  926. Use indexes for goto labels.
  927. Polling sucks.  Could this be (major) changed to be interrupt-driven?
  928. (Do people still use non-16550s out there?)
  929.